package org.leumasjaffe.initiativeTracker;
/**
 * Project: Dungeons and Dragons <br>
 * Package: 
 */


import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.UUID;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.leumasjaffe.initiativeTracker.entity.Character;
import org.leumasjaffe.initiativeTracker.entity.NPC;
import org.leumasjaffe.initiativeTracker.entity.PC;

import org.leumasjaffe.util.io.SerializeString;
import edu.wpi.heineman.xml.Message;

/**
 * Class .SaveFileTranslator in file SaveFileTranslator.java <br>
 * 
 * @author leumasjaffe
 * Created on: Aug 19, 2012
 * 
 */
@NonNullByDefault
public class SaveFileTranslator {
	static int turn;
	static int next;

	/**
	 * @param args
	 */
	@SuppressWarnings("null")
	public static void main(String[] args) {
		for (String path : args) {
			String game = UUID.randomUUID().toString().substring(0, 8), xmlString = null, suffix;
			File f = new File(path);
			if (f.isDirectory()) {
				suffix = ".mobs";
				Hashtable<String, NPC> storedMobs = new Hashtable<String, NPC>();
				for (String s : f.list()) {
					if (s.endsWith(".mob")) {
						String name = s.substring(0, s.indexOf('.'));
						NPC c = null;
						try (FileInputStream fstream = new FileInputStream(f.getAbsolutePath() +
								System.getProperty("file.separator") + s); 
								//Creates a file input stream from the source file
								DataInputStream in = new DataInputStream(fstream);
								BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
							//Creates a buffered reader around the stream
							String strLine = ""; //An empty string to read data into
							String[] strLArr;
							int x = 0; //A simple incrementing integer
							while ((strLine = br.readLine()) != null) { 
								//Read in the next line and check that it  isn't null
								if (x==0)
									name = strLine; //If its zero, store strLine in another variable
								else if (x == 1) {
									c = new NPC(Boolean.parseBoolean(strLine.substring(13))); 
									//Decode the isAllied boolean and now create the NPC
									c.setName(name); //That string we stored... it was the name
								}
								else if (x==2 && c != null) { 
									strLArr = strLine.substring(16).split(",");
									c.setHp(Integer.decode(strLArr[0]));
									c.setMaxHP(Integer.decode(strLArr[0]));
									c.setAc(Integer.decode(strLArr[1]));
									c.setFort(Integer.decode(strLArr[2]));
									c.setRef(Integer.decode(strLArr[3]));
									c.setWill(Integer.decode(strLArr[4]));
								}
								else if (x>=3)
									break; //At 3, we're done no matter how much data there is
								x++;
							}
							// Close out of all the streams top-down
						} catch (IOException e) {
							e.printStackTrace();
						}
						if (c != null)
							storedMobs.put(name, c);
					}
				}
				try {
					xmlString = SerializeString.toString(storedMobs);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			else {
				suffix = ".initiative";
				ArrayList<Character> list = importUnits(path);
				xmlString = Message.responseHeader("null") + "<initiativeResponse game='" + game + 
						"' turn='" +turn + "' next='" + next + "'>";
				for (int i = 0; i < list.size(); i++)
					xmlString += list.get(i).serialize();
				xmlString += "</initiativeResponse></response>";	
			}
			try (PrintStream ps = new PrintStream(f.getParent() + System.getProperty("file.separator") 
					+ game + suffix)) {
				ps.println(xmlString);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	private static void importNumbers(Character temp, String[] strLArr) {
		temp.setHp(Integer.decode(strLArr[0]));
		temp.setMaxHP(Integer.decode(strLArr[1]));
		temp.setAc(Integer.decode(strLArr[2]));
		temp.setFort(Integer.decode(strLArr[3]));
		temp.setRef(Integer.decode(strLArr[4]));
		temp.setWill(Integer.decode(strLArr[5]));
		temp.setInit(Integer.decode(strLArr[6]));
		temp.setId(Integer.decode(strLArr[7]));
		temp.setDot(Integer.decode(strLArr[8]));
		temp.setDis(Integer.decode(strLArr[9]));
	}

	@SuppressWarnings("null")
	private static ArrayList<Character> importUnits(String path){
		ArrayList<Character> allPieces = new ArrayList<Character>();
		try (FileInputStream fstream = new FileInputStream(path);
				DataInputStream in = new DataInputStream(fstream);
				BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
			String strLine = "";
			String[] strLArr;
			boolean isplayer = false;
			boolean isnpc = false;
			Character temp = null;
			while ((strLine = br.readLine()) != null) {
				//Read a line into the strLine variable and then check for null
				while (isplayer || isnpc) {
					//Once we have determined that we are loading a player or an npc
					if (strLine.startsWith("END OF CHARACTER")){
						//This flag means to close the generation for the character
						isplayer = false;
						isnpc = false;
						if (temp != null)
							allPieces.add(temp);
						temp = null;
					}
					else { // Otherwise...
						if (temp != null)
							if (strLine.startsWith("NUMBER VALUES:: ")) {
								//If we're reading numbers
								strLine = strLine.substring(16);
								importNumbers(temp, strLine.split(","));
							}
							else if (strLine.startsWith("BOOLEAN VALUES:: ")) {
								//If we're reading the status of the character
								strLine = strLine.substring(17); //Get rid of the Header text
								temp.readStatus(Integer.decode(strLine)); 
								//Read in the bit-string value of the status
							}
					}
					strLine = br.readLine();
				}
				if (strLine.startsWith("SET FIRST DATA:: ")) {
					//Otherwise, if we have the primary data
					strLArr = strLine.substring(17).split(",");
					turn = Integer.decode(strLArr[0]);
					next = Integer.decode(strLArr[1]);
				}
				else if (strLine.startsWith("PLAYER:: ")) { //If we have the player flag
					temp = new PC(); //Set temp to a PC and read in the rest of the data
					((PC) temp).setPlayer(strLine.substring(9));
					strLine = br.readLine().substring(9);
					strLArr = strLine.split(",");

					((PC) temp).setSurgeMax(Integer.decode(strLArr[0]));
					((PC) temp).setSurgeLeft(Integer.decode(strLArr[1]));
					((PC) temp).setTemp(Integer.decode(strLArr[2]));

					strLine = br.readLine(); //Read the next line
					temp.setName(strLine); //Set it as the name

					isplayer = true; //Flag it
				}
				else if (strLine.startsWith("NON PLAYER:: ")) { //If we read that it is an NPC
					String s = strLine.substring(13);
					Integer count = Integer.decode(s);

					strLine = br.readLine();					
					//Get whether the NPC is an ally or not from decoding strLine
					boolean isAllied = Boolean.parseBoolean(strLine.substring(13));

					temp = new NPC(isAllied, count);
					//We need that data before we generate the NPC
					strLine = br.readLine();
					temp.setName(strLine); //Read in the name
					isnpc = true; //Flag it
				}
			}
			fstream.close(); //Close out at the end
		} catch(Exception e){
		}
		return allPieces;// Return the list we've just created
	}
}